﻿using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Drawing.Actions;
using LightCAD.MathLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Color = System.Drawing.Color;
using Point = System.Drawing.Point;

namespace LightCAD.UI.Axis
{
    public partial class AxisDrawPenFrom : UserControl
    {
        public AxisDrawPenFrom()
        {
            InitializeComponent();
        }
        public void RefreshAxis(double boxWidth, double boxHeight, Dictionary<DrawDirection, AxisLineDrawDataCollection> axisLines)
        {
            double offHeight = LcAxisGrid.offValue;
            double offWidth = LcAxisGrid.offValue;

            using (Graphics g = this.CreateGraphics())
            {
                g.Clear(this.BackColor);

                if (axisLines != null)
                {
                    var topAxisline = axisLines[DrawDirection.Top];
                    var bottomxisline = axisLines[DrawDirection.Bottom];
                    var leftAxisline = axisLines[DrawDirection.Left];
                    var rightAxisline = axisLines[DrawDirection.Right];

                    #region 计算矩阵
                    double maxWidth = double.MinValue;
                    double maxhight = double.MinValue;

                    double topW = 0;
                    foreach (var lcAxisLine in topAxisline)
                    {
                        topW += lcAxisLine.Spacing;
                        if (lcAxisLine.Length > maxhight)
                        {
                            maxhight = lcAxisLine.Length;
                        }
                    }
                    maxWidth = topW;
                    double leftH = 0;
                    foreach (var lcAxisLine in leftAxisline)
                    {
                        leftH += lcAxisLine.Spacing;
                        if (lcAxisLine.Length > maxWidth)
                        {
                            maxWidth = lcAxisLine.Length;
                        }
                    }
                    if (maxhight < leftH)
                    {
                        maxhight = leftH;
                    }
                    double scale;
                    if (boxWidth > boxHeight)
                    {
                        scale = (this.Width) / (boxWidth + offWidth*2);

                    }
                    else
                    {

                        scale = (this.Height) / (boxHeight + offWidth * 2);

                    }

                    var DcsToScr = Matrix3.GetTranslate(this.Width / 2, this.Height / 2) * Matrix3.GetScale(1, -1);
                    var WcsToDcs = Matrix3.GetTranslate(0, 0) * Matrix3.GetScale(scale);
                    var WcsToScr = DcsToScr * WcsToDcs;
                    var ScrToWcs = WcsToScr.Clone().Invert();
                    var vec = new Vector2().ApplyMatrix3(ScrToWcs);
                    boxWidth = Math.Abs(vec.X * 2);
                    boxHeight = vec.Y * 2 ;
                    Vector2 offset = new Vector2(boxWidth / 2, boxHeight / 2);
                    var offMatri = WcsToScr * Matrix3.GetTranslate(-offset.X, -offset.Y);


                    #endregion
                    #region 定位点
                    var p = new Pen(Color.White, 1);
                    Vector2 srp = new Vector2(1000, 1000);
                    srp = offMatri.MultiplyPoint(srp);

                    double hsize = 5;
                    var leftTop = new Vector2(srp.X - hsize, srp.Y + hsize);
                    var rightBtm = new Vector2(srp.X + hsize, srp.Y - hsize);
                    //leftTop = offMatri.MultiplyPoint(leftTop);
                    //rightBtm = offMatri.MultiplyPoint(rightBtm);
                    var leftTopPoint = new Point((int)leftTop.X, (int)leftTop.Y);
                    var rightBtmPoint = new Point((int)rightBtm.X, (int)rightBtm.Y);
                    g.DrawLine(p, leftTopPoint, rightBtmPoint);

                    var rightTop = new Vector2(srp.X + hsize, srp.Y + hsize);
                    var leftBtm = new Vector2(srp.X - hsize, srp.Y - hsize);
                    //rightTop = offMatri.MultiplyPoint(rightTop);
                    //leftBtm = offMatri.MultiplyPoint(leftBtm);
                    var rightTopPoint = new Point((int)rightTop.X, (int)rightTop.Y);
                    var leftBtmPoint = new Point((int)leftBtm.X, (int)leftBtm.Y);
                    g.DrawLine(p, rightTopPoint, leftBtmPoint);
                    #endregion
                    if (bottomxisline.Count > 0)
                    {
                        p = new Pen(Color.Yellow, 2);
                        double lastSpacing = offWidth;

                        for (int i = 0; i < bottomxisline.Count; i++)
                        {
                            var axisLine = bottomxisline[i];
                            var length = axisLine.Length == -1 ? boxHeight : axisLine.Length + offHeight * 2;
                            for (int j = 0; j < axisLine.Count; j++)
                            {
                                lastSpacing += axisLine.Spacing;
                                Vector2 start = new Vector2(lastSpacing, 0);
                                Vector2 end = new Vector2(lastSpacing, length);
                                start = offMatri.MultiplyPoint(start);
                                end = offMatri.MultiplyPoint(end);
                                var startPoint = new Point((int)start.X, (int)start.Y);
                                var endPoint = new Point((int)end.X, (int)end.Y);
                                g.DrawLine(p, startPoint, endPoint);
                            }

                        }
                    }

                    if (topAxisline.Count > 0)
                    {
                        p = new Pen(Color.Red, 2);
                        double lastSpacing = offWidth;

                        for (int i = 0; i < topAxisline.Count; i++)
                        {
                            var axisLine = topAxisline[i];
                            var length = axisLine.Length == -1 ? boxHeight : axisLine.Length+offHeight*2;

                            for (int j = 0; j < axisLine.Count; j++)
                            {
                                lastSpacing += axisLine.Spacing;
                                Vector2 start = new Vector2(lastSpacing, boxHeight);
                                Vector2 end = new Vector2(lastSpacing, boxHeight - length);
                                start = offMatri.MultiplyPoint(start);
                                end = offMatri.MultiplyPoint(end);
                                var startPoint = new Point((int)start.X, (int)start.Y);
                                var endPoint = new Point((int)end.X, (int)end.Y);
                                g.DrawLine(p, startPoint, endPoint);
                            }

                        }
                    }


                    if (rightAxisline.Count > 0)
                    {
                        p = new Pen(Color.Blue, 2);
                        double lastSpacing = offWidth;
                        for (int i = 0; i < rightAxisline.Count; i++)
                        {
                            var axisLine = rightAxisline[i];
                            var length = axisLine.Length == -1 ? boxWidth : axisLine.Length + offHeight * 2;
                            for (int j = 0; j < axisLine.Count; j++)
                            {
                                lastSpacing += axisLine.Spacing;
                                Vector2 start = new Vector2(boxWidth, lastSpacing);
                                Vector2 end = new Vector2(boxWidth - length, lastSpacing);
                                start = offMatri.MultiplyPoint(start);
                                end = offMatri.MultiplyPoint(end);
                                var startPoint = new Point((int)start.X, (int)start.Y);
                                var endPoint = new Point((int)end.X, (int)end.Y);
                                g.DrawLine(p, startPoint, endPoint);
                            }
                        }
                    }
                    if (leftAxisline.Count > 0)
                    {
                        p = new Pen(Color.Green, 2);
                        double lastSpacing = offWidth;
                        for (int i = 0; i < leftAxisline.Count; i++)
                        {
                            var axisLine = leftAxisline[i];
                            var length = axisLine.Length == -1 ? boxWidth : axisLine.Length + offHeight * 2;
                            for (int j = 0; j < axisLine.Count; j++)
                            {
                                lastSpacing += axisLine.Spacing;
                                Vector2 start = new Vector2(0, lastSpacing);
                                Vector2 end = new Vector2(length, lastSpacing);
                                start = offMatri.MultiplyPoint(start);
                                end = offMatri.MultiplyPoint(end);
                                var startPoint = new Point((int)start.X, (int)start.Y);
                                var endPoint = new Point((int)end.X, (int)end.Y);
                                g.DrawLine(p, startPoint, endPoint);
                            }
                        }
                    }
                }

                //p.DashStyle = DashStyle.Solid;//恢复实线
                //p.EndCap = LineCap.ArrowAnchor;//定义线尾的样式为箭头
                //g.DrawLine(p, new Point(1, 1), new Point(this.Width / 2, this.Height / 2));
                //p = new Pen(Color.Green, 5);
                //p.DashStyle = DashStyle.Solid;//恢复实线
                //p.EndCap = LineCap.ArrowAnchor;//定义线尾的样式为箭头
                //g.DrawLine(p, new Point(this.Width, this.Height), new Point(this.Width / 2, this.Height / 2));
            }
        }
    }
}
